#ifndef _DAG_NODES_H_
#define _DAG_NODES_H_

#include "dag.h"
#include "dag_operators.h"

namespace dag {
	
	class DAG_API PassNode : public Node {
	public:
		PassNode();
		virtual ~PassNode() throw();
		
		const NodeTraits& traits() const;
	private:
		
		void _init(const FrameSpec& expectedInputSpec);
		const FrameSpec& _inputSpec() const;
		const FrameSpec& _outputSpec() const;
		std::auto_ptr<FrameOperator> _createForwardOp() const;
		std::auto_ptr<FrameOperator> _createReverseOp() const;
		void _learn(const FrameDepot* input, 
					const FrameDepot* output);
		
		FrameSpec m_Spec;
	};
	
	
	class DAG_API NearestNeighborNode : public Node {
	public:
		NearestNeighborNode(const FrameSpec& outputSpec);
		virtual ~NearestNeighborNode() throw();
		const NodeTraits& traits() const;
		
	private:
		void _init(const FrameSpec& expectedInputSpec);
		const FrameSpec& _inputSpec() const;
		const FrameSpec& _outputSpec() const;
		std::auto_ptr<FrameOperator> _createForwardOp() const;
		void _learn(const FrameDepot* input, 
					const FrameDepot* output);
		
		
		std::auto_ptr<FrameDepot> m_InputDepot;
		std::auto_ptr<FrameDepot> m_OutputDepot;
		FrameSpec m_InputSpec;
		FrameSpec m_OutputSpec;
	};
	
	class DAG_API PcaNode : public Node {
	public:
		PcaNode(const FrameSpec& outSpec, bool forward=true);
		virtual ~PcaNode() throw();
		const NodeTraits& traits() const;
		
	private:
		void _init(const FrameSpec& expectedInputSpec);
		const FrameSpec& _inputSpec() const;
		const FrameSpec& _outputSpec() const;
		std::auto_ptr<FrameOperator> _createForwardOp() const;
		std::auto_ptr<FrameOperator> _createReverseOp() const;
		void _learn(const FrameDepot* input, 
					const FrameDepot* output);
		
		std::auto_ptr<LinearOp> m_ForwardOp;
		std::auto_ptr<LinearOp> m_ReverseOp;
		FrameSpec m_InputSpec;
		FrameSpec m_OutputSpec;
		NodeTraits m_Traits;
		const bool m_Forward;
	};
}

#endif